package gl.live.danceshow.ui.camera;

import gl.live.danceshow.ui.widget.ProcessDialogFragment;
import gl.live.mediamux.sdk.SoxProcesser;
import gl.live.mediamux.sdk.AudioRecordCallback;
import gl.live.mediamux.sdk.VideoMuxer;

import java.io.File;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder.AudioSource;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.android.app.mvmerged.R;

/**
 *created by guolei, 18627911963
 */
public class VideoReviewActivity extends Activity implements View.OnClickListener, AudioRecordCallback {
	private static final String TAG = "VideoReviewActivity";
    private SoxProcesser mProcesser;
    
    public static final String TEST_WAV_AUDIO1  = "/sdcard/test_m.wav";//存储人声
    public static final String TEST_WAV_AUDIO2  = "/sdcard/test_music.wav";//存储伴奏
    
    private static final String TEST_VIDEO_INPUT  = "/sdcard/test.mp4";//输入视频源
    private static final String TEST_AUDIO_INPUT  = "/sdcard/test.mp3";//输入音频源
    public static final String TEST_VIDEO_OUTPUT  = "/sdcard/test_out.mp4";//输出视频
    public static final String TEST_VIDEO_MUX_OUTPUT  = "/sdcard/test_out_mux.mp4";//输出音视频混合后的视频
    private static final String TEST_WAV_AUDIO_EFFECT  = "/sdcard/test_effect.wav";//加音效的音频
    
    @Nullable
    private Uri videoUri;
    private boolean canplay = false;
	public static int res = 0;

    public static void actionReview(@NonNull Activity activity, int request, Uri videoUri) {
        Intent intent = new Intent(activity, VideoReviewActivity.class);
        intent.setData(videoUri);
        activity.startActivity(intent);
    }

    public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_review_activity);
        findViewById(R.id.buttonOK).setOnClickListener(this);
        findViewById(R.id.buttonCancel).setOnClickListener(this);
        videoUri = getIntent().getData();
        canplay = videoUri != null;
        final int bufSize = AudioTrack.getMinBufferSize(44100,
				AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
//        initSeekBar();
        TextView text = (TextView)findViewById(R.id.audio_input1);
        text.setText("人声: 录音存放->-->加音效: "+TEST_WAV_AUDIO_EFFECT);
        text = (TextView)findViewById(R.id.audio_input2);
        text.setText("伴奏: "+TEST_AUDIO_INPUT+"录像提取(video文件也可以)的伴奏-> "+TEST_WAV_AUDIO2);
        text = (TextView)findViewById(R.id.video_out_mux);
        text.setText("录制的视频,仅画面: "+TEST_VIDEO_OUTPUT+"-->混合"+TEST_VIDEO_MUX_OUTPUT);
        
    }

    /*private void initSeekBar () {
    	SeekBar bar = (SeekBar)findViewById(R.id.vol);
    	bar.setOnSeekBarChangeListener(monSeekBarListener);
    	bar = (SeekBar)findViewById(R.id.flanger);
    	bar.setOnSeekBarChangeListener(monSeekBarListener);
    	bar = (SeekBar)findViewById(R.id.pitch);
    	bar.setOnSeekBarChangeListener(monSeekBarListener);
    	bar = (SeekBar)findViewById(R.id.highpass);
    	bar.setOnSeekBarChangeListener(monSeekBarListener);
    	bar = (SeekBar)findViewById(R.id.reverb);
    	bar.setOnSeekBarChangeListener(monSeekBarListener);
    	
    }*/
    
    SeekBar.OnSeekBarChangeListener monSeekBarListener =  new SeekBar.OnSeekBarChangeListener() {
		
		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {
			
		}
		
		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {
			
		}
		
		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {
			Log.d(TAG,"onProgressChanged "+progress);
//			switch (seekBar.getId()) {
//			case R.id.vol:
//				mProcesser.setVol(progress);
//				break;
//			case R.id.flanger:
//				mProcesser.setflanger(progress);
//				break;
//			case R.id.highpass:
//				mProcesser.setHighPass(progress);
//				break;
//			case R.id.pitch:
//				mProcesser.setPitch(progress);
//				break;
//			case R.id.reverb:
//				mProcesser.setReverB(progress);
//				break;
//			default:
//				break;
//			}
		}
	};
    
    @SuppressLint("NewApi") @Override
    protected void onResume() {
        super.onResume();
		if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
	              != PackageManager.PERMISSION_GRANTED && Build.VERSION_CODES.M <= Build.VERSION.SDK_INT) {
	          //申请WRITE_EXTERNAL_STORAGE权限
	          requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE,android.Manifest.permission.CAMERA},
	                  1);
	      }
		if (ContextCompat.checkSelfPermission(this,android.Manifest.permission.CAMERA)
	              != PackageManager.PERMISSION_GRANTED && Build.VERSION_CODES.M <= Build.VERSION.SDK_INT) {
	          requestPermissions(new String[]{android.Manifest.permission.CAMERA},
	                  2);
	      }
        
        
        if(!canplay) {
        	return;
        }
        
        
		
    }
    private void configAudioRecoder(int sr, int channelConfig, int audioFormat,int bufferSizeInBytes) {
		try {
			mAudioRecord =  new AudioRecord(AudioSource.MIC, sr, channelConfig, audioFormat, bufferSizeInBytes);
		} catch (IllegalArgumentException e) {
			Log.w(TAG,"mAudioRecord create fail....");
		}
	}
	
	private void startAudioRecord() {
		if(mAudioRecord!= null) {
			mAudioRecord.startRecording();
		}
	}
	
	private void stopAudioRecord() {
		if(mAudioRecord!= null) {
			mAudioRecord.stop();
		}
	}
	
	private void releaseAudioRecord() {
		if(mAudioRecord!= null) {
			mAudioRecord.release();
		}
		mAudioRecord = null;
	}
    private ProcessDialogFragment mDialog;
    private short[] mAudioRecordBuffer;
    private AudioRecord mAudioRecord;
    private class MyAsyncTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... params) {
			Log.d("guolei","addEffect begin...");
			count = 0;
			int size = AudioRecord.getMinBufferSize(
					44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
					AudioFormat.ENCODING_PCM_16BIT);
			mAudioRecordBuffer = new short[size];
			Log.d(TAG, "configAudioRecoder min size " + size);
			configAudioRecoder(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
					AudioFormat.ENCODING_PCM_16BIT, size);
			startAudioRecord();
			mProcesser.init();
			//for example: add effect params
			
			mProcesser.setEffect();
			mProcesser.processEffect(TEST_WAV_AUDIO1,TEST_WAV_AUDIO_EFFECT);
			mProcesser.release();
			stopAudioRecord();
			releaseAudioRecord();
			Log.d("guolei","addEffect end...");
			return null;
		}
    	
		protected  void onProgressUpdate(Void[] values) {
			
		};
		
		
		protected void onPostExecute(Void result) {
			mDialog.dismiss();
			Toast.makeText(VideoReviewActivity.this, "加入音效成功，正在混音", Toast.LENGTH_SHORT).show();
//			new EncodeAudioTask().execute();//new MixAudioTask().execute();
		};
    }
    
    
    @Override
    public void onClick(@NonNull View v) {
        int i = v.getId();
        if (i == R.id.buttonOK) {
        	if(!new File(TEST_WAV_AUDIO_EFFECT).exists()) return;
        	if(!new File(TEST_WAV_AUDIO2).exists()) return;
        	if(!new File(TEST_VIDEO_OUTPUT).exists()) return;
        	
        	mDialog = new ProcessDialogFragment();
        	mDialog.setCancelable(false);
        	mDialog.show(getFragmentManager(), "process");
        	mProcesser = new SoxProcesser();
            mProcesser.setAudioRcordCallback(this);
//        	new MyAsyncTask().execute();
        	new EncodeAudioTask().execute();//new MixAudioTask().execute();
        } else if (i == R.id.buttonCancel) {
        	CameraPreviewActivity.actionRecord(this, 1000, TEST_AUDIO_INPUT/*TEST_VIDEO_INPUT*/, "合舞测试DEMO",TEST_VIDEO_INPUT);
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    	super.onActivityResult(requestCode, resultCode, data);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
    }
    
//    class MixAudioTask extends AsyncTask<Void, Double, Boolean> {
//
//		@Override
//		protected Boolean doInBackground(Void... params) {
//			List<String> addAudioTracks = new ArrayList<String>();
//			addAudioTracks.add(TEST_WAV_AUDIO_EFFECT);
//			addAudioTracks.add(TEST_WAV_AUDIO2);
//			
//			int audioSize = addAudioTracks.size();
//			Log.d("guolei","doInBackground in");
//			boolean isSingleAudio = false;
////			String rawAudioFile = null;
////			if(audioSize == 1){
////				isSingleAudio = true;
////				rawAudioFile = addAudioTracks.iterator().next().fileUrl;
////			}
//			
//			if(!isSingleAudio){
//				File[] rawAudioFiles = new File[audioSize];
//				StringBuilder sbMix = new StringBuilder();
//				int index = 0;
//				for (String audioEntry : addAudioTracks) {
//					rawAudioFiles[index++] = new File(audioEntry);
//					sbMix.append(audioEntry);
//				}
//				final String mixFilePath = TEST_WAV_AUDIO_MIX+".temp";//MD5Util.getMD5Str(sbMix.toString());
//				Log.d("guolei","mixFilePath "+mixFilePath);
//				try {
//					MultiAudioMixer audioMixer = MultiAudioMixer.createAudioMixer();
//
//					audioMixer.setOnAudioMixListener(new OnAudioMixListener() {
//
//						FileOutputStream fosRawMixAudio = new FileOutputStream(mixFilePath);
//
//						@Override
//						public void onMixing(byte[] mixBytes) throws IOException {
//							fosRawMixAudio.write(mixBytes);
//						}
//
//						@Override
//						public void onMixError(int errorCode) {
//							try {
//								if(fosRawMixAudio != null)
//									fosRawMixAudio.close();
//							} catch (IOException e) {
//								e.printStackTrace();
//							}
//						}
//
//						@Override
//						public void onMixComplete() {
//							try {
//								
//								
//								
//								if(fosRawMixAudio != null)
//									fosRawMixAudio.close();
//								FileInputStream in = new FileInputStream(mixFilePath);
//								FileOutputStream out = new FileOutputStream(TEST_WAV_AUDIO_MIX);
//								long size = in.getChannel().size();
//								Log.d(TAG,"size "+size);
//								int samplerate = 44100;
//								int channels =2;
//								int bitrate = (16 * samplerate * channels) / 8;
//								FileUtil.WriteWaveFileHeader(out, size,
//										size + 36, samplerate, channels,
//										bitrate);
//								byte[] data = new byte[bitrate];
//								while (in.read(data) != -1) {
//					                out.write(data);
//					            }
//								Log.d(TAG,"out size "+out.getChannel().size());
//								 in.close();
//						         out.close();
//								
//							} catch (IOException e) {
//								e.printStackTrace();
//							}
//						}
//
//					});
//					audioMixer.mixAudios(rawAudioFiles);
////					rawAudioFile = mixFilePath;
//				} catch (FileNotFoundException e) {
//					e.printStackTrace();
//				}
//			}
////			AudioEncoder accEncodser =  AudioEncoder.createAccEncoder(rawAudioFile);
////			String finalMixPath = MainApplication.RECORD_AUDIO_PATH + "/MixAudioTest.aac";
////			accEncoder.encodeToFile(finalMixPath);
////			mFinalMixAudioFile = finalMixPath;
//			Log.d("guolei","doInBackground end");
//			return true;
//		}
//
//		@Override
//		protected void onPostExecute(Boolean result) {
//			super.onPostExecute(result);
//			Toast.makeText(VideoReviewActivity.this, "混音成功，正在合成编码成ACC格式", Toast.LENGTH_SHORT).show();
//			
//			new EncodeAudioTask().execute();
//		}
//	}
    
    
    class EncodeAudioTask extends AsyncTask<Void, Double, Boolean> {

		@Override
		protected Boolean doInBackground(Void... params) {
			Log.d("guolei","EncodeAudioTask doInBackground in");
//			initMediaMuxEnv(TEST_VIDEO_OUTPUT);
//			AudioEncoder accEncoder =  AudioEncoder.createAccEncoder(TEST_WAV_AUDIO_MIX);
//			accEncoder.encodeToMuxer(mMpeg4Muxer);
			VideoMuxer muxer = VideoMuxer.createVideoMuxer(TEST_VIDEO_MUX_OUTPUT);
			muxer.mixRawAudio(TEST_VIDEO_OUTPUT, TEST_WAV_AUDIO_EFFECT, TEST_WAV_AUDIO2);
			Log.d("guolei","EncodeAudioTask doInBackground end");
			return true;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			Toast.makeText(VideoReviewActivity.this, "成功合成编码!", Toast.LENGTH_SHORT).show();
			mDialog.dismiss();
		}
	}

    int count = 0;
	@Override
	public short[] readAudioRecordBuffers() {
		if (mAudioRecord == null || count >=500)
		return null;
		count++;
		int a = mAudioRecord.read(mAudioRecordBuffer, 0, mAudioRecordBuffer.length);
		Log.d(TAG,"a = "+a);
		return mAudioRecordBuffer;
	}
}